
import sys
import datetime

from dexen.user.libs import constants as dc, server_api
from dexen.user.libs import gui_api
from dexen.user.libs.algorithms import ea

from libs import constants, input_reading
from libs.visualizer import RectangleVisualizer

pop_api = server_api.PopAPIFactory()

boxes = input_reading.read_input()
birth_no = 0

pop_graph = gui_api.GraphAPIFactory(
    type=gui_api.POP_GRAPH, 
    x_axis_name="No of Births", 
    y_axis_name="Population Size",
    title="Population Graph"
)

obj_graph1 = gui_api.GraphAPIFactory(
    type=gui_api.OBJ_GRAPH, 
    x_axis_name="No of Births", 
    y_axis_name="Width",
    title="Width Objective Graph"
    
)

obj_graph2 = gui_api.GraphAPIFactory(
    type=gui_api.OBJ_GRAPH, 
    x_axis_name="No of Births", 
    y_axis_name="Height",
    title="Height Objective Graph"
)

pareto_graph = gui_api.GraphAPIFactory(
    type=gui_api.PARETO_GRAPH, 
    x_axis_name="Width", 
    y_axis_name="Height",
    title="Pareto Graph"
)


def visualize_flex():
    global birth_no
    
    birth_no += 200

    no_inds = pop_api.count_live_individuals(at_time=birth_no)
    pop_graph.addData(x=birth_no, y=no_inds)  
    
    #print birth_no, no_inds
        
    inds = \
    pop_api.download_live_individuals(
        select=(constants.WIDTH, constants.HEIGHT, constants.GENOTYPE, 
                constants.PHENOTYPE), 
        where=(
            (constants.WIDTH, dc.NOT_EQUAL, None),
            (constants.HEIGHT, dc.NOT_EQUAL, None),
        ), 
        at_time=birth_no,
        exclusive_use=False # You can change it to TRUE because you are sending back the individuals
    )
    
    min_value = min([ind[constants.WIDTH] for ind in inds])
    max_value = max([ind[constants.WIDTH] for ind in inds])
    
    #print min_value, max_value
    
    obj_graph1.addData(birth_no, min_value)
    obj_graph1.addData(birth_no, max_value)
    #obj_graph1.addData(birth_no, sum([ind["min_width"] for ind in inds])/len(inds))

    min_value = min([ind[constants.HEIGHT] for ind in inds])
    max_value = max([ind[constants.HEIGHT] for ind in inds])
    
    #print min_value, max_value
    
    obj_graph2.addData(birth_no, min_value)
    obj_graph2.addData(birth_no, max_value)
    #obj_graph2.addData(birth_no, sum([ind["min_height"] for ind in inds])/len(inds))

    env_selector = ea.EnvironmentalSelection() 
    env_selector.setObjectives(
        (constants.WIDTH, dc.MINIMIZE),
        (constants.HEIGHT, dc.MINIMIZE)
    )
    pareto_front = env_selector.filterDominatedOnes(inds)

    create_images(pareto_front)

    for ind in pareto_front:
        pareto_graph.addData(ind[constants.WIDTH], ind[constants.HEIGHT], ind["id"])
    
    #pop_api.uploadIndividuals(pareto_front)
    return pareto_front
        
def create_images(individuals):
    for individual in individuals:
        rv = RectangleVisualizer(200, 200, boxes)
        rv.draw_individual(individual)
        pop_api.setImage(individual, rv.getPNGImage(), keep=True)
        